package qf.index;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

public class ReadTc {

    public static void main(String[] args) throws SQLException {

        String newDataName = "scholar_25_02.";
        String summaryTable = newDataName + "unified_search_summary_0120";
        String citationTable = newDataName + "basic_core_paper_citation";
        String referenceTable = newDataName + "basic_core_paper_reference";
        String limit = "";
//        String limit = " limit 1";
        upDataCitation(summaryTable, citationTable, referenceTable, limit);

    }

    public static void upDataCitation(String summaryTable, String citationTable, String referenceTable, String limit) throws SQLException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        System.out.println(format.format(new Date()) + " 程序开始了~~~");

        Db.use().execute("truncate table " + referenceTable);
        // 为什么将自增id分四次跑，原因是当电脑内存不够大时，容易出现内存溢出，分四次后数据也是正确的。本次maxId: 115043920，用于
        insertReferenceTable(citationTable, "id", "pid`,`citation_id", referenceTable, 0, 30000000, limit);
        System.out.println("\033[31;1m" + format.format(new Date()) + " ⒁ 更新被引第一次，表名：" + citationTable + Utils.printMemoryStr() + "\033[0m");

        insertReferenceTable(citationTable, "id", "pid`,`citation_id", referenceTable, 30000000, 60000000, limit);
        System.out.println("\033[31;1m" + format.format(new Date()) + " ⒁ 更新被引第二次，表名：" + citationTable + Utils.printMemoryStr() + "\033[0m");

        insertReferenceTable(citationTable, "id", "pid`,`citation_id", referenceTable, 60000000, 90000000, limit);
        System.out.println("\033[31;1m" + format.format(new Date()) + " ⒁ 更新被引第三次，表名：" + citationTable + Utils.printMemoryStr() + "\033[0m");

        insertReferenceTable(citationTable, "id", "pid`,`citation_id", referenceTable, 90000000, 215043921, limit);
        System.out.println("\033[31;1m" + format.format(new Date()) + " ⒁ 更新被引第四次，表名：" + citationTable + Utils.printMemoryStr() + "\033[0m");

        // update unified_search_summary_0120 AS a join basic_core_paper_citation AS b ON a.aid = b.pid SET a.citations = b.citation_id;
        // update unified_search_summary_0120 AS a join basic_core_paper_reference AS b ON a.aid = b.pid SET a.references = b.reference_id;

        Db.use().execute("update " + summaryTable + " AS a join " + citationTable + " AS b ON a.aid = b.pid SET a.citations = b.citation_id;");
        System.out.println("\033[31;1m" + format.format(new Date()) + " ⒂ 执行sql语句第一次结束。" + "\033[0m");
        Db.use().execute("update " + summaryTable + " AS a join " + referenceTable + " AS b ON a.aid = b.pid SET a.references = b.reference_id;");
        System.out.println("\033[31;1m" + format.format(new Date()) + " ⒂ 执行sql语句第二次结束。" + "\033[0m");

    }

    public static void insertReferenceTable(String citationTable, String autoId, String field, String referenceTable, int min, int max, String limit) throws SQLException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int onePageNum = 100000;
        List<Entity> tableNum = Db.use().query("select count(1) as count from " + citationTable);
        Map<Integer, Set<Integer>> pidAndPidSetMap = new HashMap<>();
        int maxId = 0;
        if (tableNum.get(0).getInt("count") > 0) {
            int tableMax = Db.use().queryNumber("select max(" + autoId + ") from " + citationTable).intValue();
            Collection<Integer> tableList = new ArrayList<>();
            NumberUtil.appendRange(0, tableMax + onePageNum, onePageNum, tableList);
            for (Integer startId : tableList) {
                List<Entity> tableData = Db.use().query("select `" + autoId + "`,`" + field + "` from " + citationTable + " where " + autoId + " between " + startId + " and " + (startId + onePageNum - 1) + limit);

                for (Entity entry : tableData) {
                    Integer pid = entry.getInt("pid");
                    String citationId = entry.getStr("citation_id");
                    if (null != pid && pid > 0 && null != citationId && !citationId.isEmpty()) {
                        String[] split = citationId.replace(" ", "").trim().split(",");
                        for (String ids : split) {
                            if (NumberUtil.isInteger(ids)) {
                                int id = Integer.parseInt(ids);
                                maxId = Math.max(maxId, id);
                                if (id >= min && id < max) {
                                    putIntSetIntMap(pidAndPidSetMap, id, pid);
                                }
                            }
                        }
                    }
                }
            }
        }
//        System.out.println("maxId: " + maxId);
        pidAndPidSetMap.keySet().parallelStream().forEach(pid -> {
            Set<Integer> idSet = pidAndPidSetMap.get(pid);
            String ids = CollUtil.join(idSet, ",");
            try {
                Db.use().insert(Entity.create(referenceTable).set("pid", pid).set("reference_total", idSet.size()).set("reference_id", ids));
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
    }

    public static void putIntSetIntMap(Map<Integer, Set<Integer>> finishAidListSetMap, int max, int min) {
        finishAidListSetMap.compute(max, (k, v) -> {
            if (v == null) {
                v = new ConcurrentHashSet<>();
            }
            v.add(min);
            return v;
        });
    }


}
